package cn.jjxx.modules.portal.service.impl;

import cn.jjxx.core.model.AjaxJson;
import cn.jjxx.core.utils.*;
import cn.jjxx.modules.portal.dto.UserDto;
import cn.jjxx.modules.portal.enums.RoleEnum;
import cn.jjxx.modules.portal.service.IRegisterService;
import cn.jjxx.modules.portal.utils.MessageConfig;
import cn.jjxx.modules.sms.service.ISmsSendLogService;
import cn.jjxx.modules.sys.entity.Staff;
import cn.jjxx.modules.sys.entity.User;
import cn.jjxx.modules.sys.entity.UserRole;
import cn.jjxx.modules.sys.service.IStaffService;
import cn.jjxx.modules.sys.service.IUserRoleService;
import cn.jjxx.modules.sys.service.IUserService;
import cn.jjxx.modules.sys.service.impl.PasswordService;
import org.framework.customutil.UUIDGenerator;
import org.framework.superutil.j2se.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.text.MessageFormat;

@Transactional
@Service("registerService")
public class RegisterServiceImpl implements IRegisterService {
    /**用户注册手机短信验证码缓存*/
    private final static String REG_CODE_EHCAHE_NAME = "userRegCodeCache";
    /**根据IP记录用户注册次数*/
    private final static String REG_CODE_COUNT_BY_IP_EHCAHE_NAME = "regCodeCountByIPCache";
    /**同IP在1小时内连续最大获取注册验证码次数*/
    private int maxOfRegSMSCode = Integer.parseInt(JeewebPropertiesUtil.getConfig("maxRegSMSCode"));
    /**用户注册时手机验证码缓存前缀*/
    private final static String CODE_PREFIX = "RegCode_";
    /**同一个IP注册时获取验证码次数缓存前缀*/
    private final static String REG_COUNT_PREFIX = "RegCount_";

    @Autowired
    PasswordService passwordService;
    @Autowired
    private IStaffService staffService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ISmsSendLogService smsSendLogService;

    @Override
    public AjaxJson getSMSCodeByReg(HttpServletRequest request, String phone) {
        AjaxJson result = new AjaxJson();
        if (StringUtils.isBlank(phone)) {
            result.fail("手机号码不能为空");
            return result;
        }
        User exist = userService.findByPhone(phone);
        if (exist != null) {
            result.fail("手机号码已存在，不能重复注册。");
            return result;
        }
        result.success("操作成功");
        String ip = IpUtils.getIpAddr(request);
        int i = getRegCountByIP(ip);
        if (i > maxOfRegSMSCode) {
            result.fail("您的操作异常，请稍后再试。");
            return result;
        }
        // 验证码
        String randomNumber = RandomUtils.getRandomNumber(6);
        // 将验证码存入缓存
        CacheUtils.put(REG_CODE_EHCAHE_NAME, CODE_PREFIX + phone, randomNumber);
        putRegCountByIP(ip);
        String msg = MessageFormat.format(MessageConfig.DEFAULT_CODE_MESSAGE, randomNumber);
        smsSendLogService.writeSmsLog(phone, msg, StringUtils.randomUUID());

        result.setData("操作成功");
        return result;
    }

    /**
     * 防止恶意注册，将注册者的IP及获取注册验证码次数写入缓存，有效期1天。
     * 如果同一个IP重复调取注册码超过设定的次数，则1小时内不允许注册
     * @param ip ip
     * @author mali
     * @date 2019-01-16
     */
    private void putRegCountByIP(String ip) {
        Object countByIp = CacheUtils.get(REG_CODE_COUNT_BY_IP_EHCAHE_NAME, REG_COUNT_PREFIX + ip);
        int i = 1;
        if (countByIp != null) {
            i = Integer.parseInt(countByIp.toString());
            i++;
        }
        CacheUtils.put(REG_CODE_COUNT_BY_IP_EHCAHE_NAME, REG_COUNT_PREFIX + ip, i);
    }

    /**
     * 获取注册时同一IP获取验证码次数
     * @param ip ip
     * @return 次数
     * @author mali
     * @date 2019-01-16
     */
    private int getRegCountByIP(String ip) {
        Object countByIp = CacheUtils.get(REG_CODE_COUNT_BY_IP_EHCAHE_NAME, REG_COUNT_PREFIX + ip);
        int i = 0;
        if (countByIp != null) {
            i = Integer.parseInt(countByIp.toString());
        }
        return i;
    }

    @Override
    public AjaxJson register(HttpServletRequest request, UserDto userDto) {
        AjaxJson result = new AjaxJson();
        User exist = userService.findByPhone(userDto.getPhone());
        if (exist != null) {
            result.fail("手机号码已存在，不能重复注册。");
            return result;
        }

        result.success("注册成功");

        String codeOfCache = (String) CacheUtils.get(REG_CODE_EHCAHE_NAME, CODE_PREFIX + userDto.getPhone());
        if (StringUtils.isNotBlank(codeOfCache) && userDto.getVcode().equals(codeOfCache)) {
            // userId
            String userId = UUIDGenerator.generate();
            // staffId
            String staffId = UUIDGenerator.generate();
            // 如果验证码匹配，写入 用户、职员表、角色表
            // 写入职员信息
            Staff staff = new Staff();
            staff.setId(staffId);
            staff.setUserId(userId);
            staff.setOrgId(UserDto.PORTAL_ORG);
            // 职员编号未处理并发问题，实际上扶贫项目也不需要
//            staff.setCode(SpringContextHolder.getBean(StaffController.class).createStaffNum(UserDto.PORTAL_ORG));
            staff.setName(userDto.getPhone());
            staff.setMoblie(userDto.getPhone());
            staffService.insert(staff);
            // 写入用户信息
            User user = new User();
            user.setId(userId);
            user.setStaffId(staffId);
            user.setUsername(userDto.getPhone());
            user.setRealname(userDto.getPhone());
            user.setPhone(userDto.getPhone());
            user.setPassword(userDto.getPassword());
            user.setOrgId(UserDto.PORTAL_ORG);
            user.setMorgId(UserDto.PORTAL_ORG);
            user.setNikeName(userDto.getPhone());
            user.setType(RoleEnum.getValue(userDto.getType()).getDictCode());
            userService.insert(user);
            // 写入用户角色信息
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(RoleEnum.getValue(userDto.getType()).getId());
            userRoleService.insert(userRole);
        } else {
            result.fail("验证码验证错误。");
        }

        return result;
    }

}
